/**
 *
 * @param table {Table}
 */
export const Entity = async(table) => {
  if (table.isJpaModel) {
    const JpaEntity = (await import('./entity/JpaEntity'))
    return JpaEntity.default(table)
  } else {
    const SqlEntity = (await import('./entity/SqlEntity.js'))
    return SqlEntity.default(table)
  }
}

/**
 *
 * @param table {Table}
 */
export const InsertDTO = async(table) => {
  const InsertDTO = (await import('./entity/InsertDTO'))
  return InsertDTO.default(table)
}
/**
 *
 * @param table {Table}
 */
export const UpdateDTO = async(table) => {
  const UpdateDTO = (await import('./entity/UpdateDTO'))
  return UpdateDTO.default(table)
}
/**
 *
 * @param table {Table}
 */
export const JsEntity = async(table) => {
  const JsEntity = (await import('./js-entity/JsEntity'))
  return JsEntity.default(table)
}

/**
 *
 * @param table {Table}
 */
export const Http = async(table) => {
  const {
    author,
    comment,
    date,
    columns
  } = table
  return `# **********************************************************************************************************************
# ${comment} V20220301
# @author ${author} on ${date} 
# 
# ${columns.map(col =>
    `"${col.name}":`.padEnd(30, ' ',)
    + `# ${col.comment}`
  ).join('\n# ')}
# **********************************************************************************************************************
${(await import('./http/page')).pageAuthInstall(table)}
${(await import('./http/list')).listAuthUninstall(table)}
${(await import('./http/findById')).findByIdAuthInstall(table)}
${(await import('./http/save')).saveAuthInstall(table)}
${(await import('./http/update')).updateAuthInstall(table)}
${(await import('./http/deleteById')).deleteByIdAuthUninstall(table)}
${(await import('./http/markDeleteById')).markDeleteByIdAuthInstall(table)}
`
}

/**
 *
 * @param table {Table}
 */
export const Controller = async(table) => {
  const {
    author,
    pkg,
    comment,
    date,
    names: {
      JavaName,
      java_name,
      pkgName
    }
  } = table
  return `package ${pkg}.business.${pkgName}.controller;

${(await import('./controller/importPackage')).importPackageAuthInstall(table)}

/**
 * 对外接口：${comment} V20220301
 *
 * @author ${author} on ${date} 
 */
@Api(tags = "${comment}")
//@ApiSort() // 控制接口排序// <-
@RequestMapping("/${java_name}")
@Controller
@Slf4j
@RequiredArgsConstructor
public class ${JavaName}Controller {

    private final ${JavaName}Service service;

${(await import('./controller/page')).pageAuthInstall(table)}
${(await import('./controller/list')).listAuthUninstall(table)}
${(await import('./controller/findById')).findByIdAuthInstall(table)}
${(await import('./controller/insert')).insertAuthInstall(table)}
${(await import('./controller/update')).updateAuthInstall(table)}
${(await import('./controller/markDeleteById')).markDeleteByIdAuthInstall(table)}
${(await import('./controller/deleteById')).deleteByIdAuthUninstall(table)}
}
`
}

/**
 *
 * @param table {Table}
 */
export const Service = async(table) => {
  const {
    author,
    pkg,
    comment,
    idType,
    date,
    names: {
      TabName,
      JavaName,
      pkgName
    }
  } = table
  return `package ${pkg}.business.${pkgName}.service;
${(await import('./service/importPackage')).importPackageAuthInstall(table)}
/**
 * 服务接口实现类：${comment} V20220301// <-
 *
 * @author ${author} on ${date} 
 */
@Slf4j
@Service
@Validated
@RequiredArgsConstructor
public class ${JavaName}Service
//      , I${TabName}Cache
{
    private final ${JavaName}Repository repository;
//     /** // 若使用缓存需要解开代码
//      * 获取当前缓存管理器，用于代码控制缓存
//      *
//      * @return {@link Cache}
//      */
//     public Cache getCache() {
//         return Objects.requireNonNull(getCacheManager().getCache(CACHE_ROW_BY_ID), "未获取到缓存管理对象:".concat(CACHE_ROW_BY_ID));
//     }
//
//     /** // 若使用缓存需要解开代码
//      * 清除多个 key 对应的缓存
//      *
//      * @param ids {@link ${TabName}#getId()}
//      */
//     public void clearKeys(final Collection<${idType}> ids) {
//         ids.stream().distinct().forEach(id -> getCache().evict(id));
//     }

${(await import('./service/insert')).insertAuthInstall(table)}
${(await import('./service/update')).updateAuthInstall(table)}
${(await import('./service/deleteById')).deleteByIdAuthUninstall(table)}
${(await import('./service/markDeleteById')).markDeleteByIdAuthInstall(table)}
${(await import('./service/findById')).findByIdAuthInstall(table)}
${(await import('./service/page')).pageAuthInstall(table)}
${(await import('./service/list')).listAuthUninstall(table)}
${(await import('./service/listByIds')).listByIdsAuthInstall(table)}
${(await import('./service/mapByIds')).mapByIdsAuthInstall(table)}
}
`
}

/**
 *
 * @param table {Table}
 */
export const Repository = async(table) => {
  const {
    author,
    pkg,
    comment,
    idType,
    date,
    isJpaModel,
    isSqlModel,
    modeNameLowerCase,
    names: {
      TabName,
      JavaName,
      tabName,
      pkgName
    }
  } = table
  return `package ${pkg}.business.${pkgName}.dao.${modeNameLowerCase};
${(await import('./repository/importPackage')).importPackageAuthInstall(table)}
/**
 * 数据操作：${comment} V20220301// <-
 *
 * @author ${author} on ${date} 
 */
${isSqlModel ? '@Repository' : ''}
${isSqlModel ? '@RequiredArgsConstructor' : ''}
public ${isJpaModel ? 'interface' : 'class'} ${JavaName}Repository 
        ${isJpaModel ? `extends        JpaRepository<${TabName}, ${idType}>,` : ''}
        ${isJpaModel ? `        org.springframework.data.querydsl.QuerydslPredicateExecutor<${TabName}>` : ''}
{
    ${isSqlModel ? '@Getter(AccessLevel.PRIVATE) private final SQLQueryFactory queryFactory;' : ''}
    
    // 每个 DAO 层顶部只能有一个查询实体,且必须以 table 命名,表示当前操作的数据库表. 当 table 作为主表的连接查询方法也必须写在这个类
    Q${TabName} table = Q${TabName}.${tabName};

${'' && (await import('./repository/IJavaNameRepository')).iJavaNameRepositoryAuthUninstall(table)}
${(await import('./repository/insert')).insertAuthInstall(table)}
${(await import('./repository/update')).updateAuthInstall(table)}
${(await import('./repository/deleteById')).deleteByIdAuthUninstall(table)}
${(await import('./repository/markDeleteById')).markDeleteByIdAuthInstall(table)}
${(await import('./repository/sql/findById')).findByIdAuthInstall(table)}
${(await import('./repository/sql/findAllById')).findAllByIdAuthInstall(table)}
${(await import('./repository/findOne')).findOneAuthInstall(table)}
${(await import('./repository/findCacheById')).findCacheByIdAuthUninstall(table)}
${(await import('./repository/mapByIds')).mapByIdsAuthInstall(table)}
${(await import('./repository/count')).countAuthInstall(table)}
${(await import('./repository/pageIds')).pageIdsAuthInstall(table)}
${(await import('./repository/page')).pageAuthInstall(table)}
${(await import('./repository/listIds')).listIdsAuthInstall(table)}
${(await import('./repository/listByIds')).listByIdsAuthInstall(table)}
${(await import('./repository/list')).listAuthInstall(table)}
${(await import('./repository/forEach')).forEachAuthInstall(table)}
}
`
}

/**
 *
 * @param table {Table}
 */
export const JsService = async(table) => {
  const {
    author,
    comment,
    date,
    existDeletedColumn,
    names: {
      java_name,
      JavaName
    }
  } = table
  return `import http from './http'
import throttle from 'lodash/throttle'
import Page from '../utils/entity/Page'
import Result from '../utils/entity/Result'
import ${JavaName} from './entity/${JavaName}'

const pageURL = '/${java_name}/page/{number}/{limit}' // 分页：多条件批量查询
// const listURL = '/${java_name}' // 多条件批量查询，不分页
const findByIdURL = '/${java_name}/{encryptId}' // 按 encryptId 查询单条记录
const saveURL = '/${java_name}' // 新增
const updateURL = '/${java_name}/{encryptId}' // 修改
// const deleteByIdURL = '/${java_name}/{encryptId}' // 按 encryptId 删除
// const deleteByIdsURL = '/${java_name}' // 按 encryptId 批量删除
${existDeletedColumn ? '' : '//'}const markDeleteByIdURL = '/${java_name}/{encryptId}' // 按 encryptId 逻辑删除
${existDeletedColumn ? '' : '//'}const markDeleteByIdsURL = '/${java_name}' // 按 encryptId 批量逻辑删除

/**
 * 后台服务请求：${comment} V20220301
 * @author ${author} on ${date} 
 */
export default class ${JavaName}Service {
${(await import('./js-service/pageable')).pageableInstall(table)}
${(await import('./js-service/list')).listUninstall(table)}
${(await import('./js-service/findById')).findByIdInstall(table)}
${(await import('./js-service/save')).saveInstall(table)}
${(await import('./js-service/update')).updateInstall(table)}
${(await import('./js-service/markDeleteById')).markDeleteByIdInstall(table)}
${(await import('./js-service/deleteById')).deleteByIdUninstall(table)}
}
`
}

/**
 *
 * @param table {Table}
 */
export const JsServiceTest = async(table) => {
  const {
    author,
    comment,
    date,
    existDeletedColumn,
    names: {JavaName}
  } = table
  return `/**
 * 后台服务请求测试：${comment} V20220301// <-
 * @author ${author} on ${date} 
 */
import random from 'lodash/random'
import sample from 'lodash/sample'
import sampleSize from 'lodash/sampleSize'
import ${JavaName} from '../../src/api/entity/${JavaName}'
import ${JavaName}Service from '../../src/api/${JavaName}Service'
import UserServiceTest, {sessionUser} from './UserService.test'
import OrderBy from '../../src/utils/entity/OrderBy'
import Page from '../../src/utils/entity/Page'

class ${JavaName}ServiceTest {
  
${(await import('./js-service-test/pageable')).pageableInstall(table)}
${(await import('./js-service-test/list')).listUninstall(table)}
${(await import('./js-service-test/findById')).findByIdInstall(table)}
${(await import('./js-service-test/save')).saveInstall(table)}
${(await import('./js-service-test/update')).updateInstall(table)}
${(await import('./js-service-test/markDeleteById')).markDeleteByIdInstall(table)}
${(await import('./js-service-test/deleteById')).deleteByIdUninstall(table)}
  
  /**
   * 测试全部
   * @return {Promise<void>}
   */
  async testAll() {
    const moduleName = '${comment}'
    console.info(\`\\n\\n\\n\\n\\n\\n\\n\\n\${moduleName}：start \${'*'.repeat(200)}\\n\${__filename}\\n\\n\\n\`)
    await Promise.resolve()
      // admin 登录
      .then(() => UserServiceTest.loginAdminBasic())
      // 开始
      .then(() => this.save()).then(() => console.log(''))
      .then(() => this.update()).then(() => console.log(''))
      ${existDeletedColumn ? '' : '//'}.then(() => this.markDeleteById()).then(() => console.log(''))
      // .then(() => this.deleteById()).then(() => console.log(''))
      .then(() => this.pageable()).then(() => console.log(''))
      // .then(() => this.list()).then(() => console.log(''))
      .then(() => this.findById()).then(() => console.log(''))
      // 结束
      .then(() => console.info(\`\${moduleName}：end \${'*'.repeat(200)}\\n\\n\\n\\n\\n\`))
      .catch((e) => {
        console.error(e)
        throw new Error(\`\${moduleName}：异常：\${e.message}\`)
      })
  }
}
export default new ${JavaName}ServiceTest()
`
}
